package info.ask4research.web;

import info.ask4research.model.UnitOfLearning;
import info.ask4research.model.User;
import info.ask4research.service.IUnitOfLearningService;
import info.ask4research.service.impl.UserService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.springframework.stereotype.Controller;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.sun.org.apache.xpath.internal.XPathAPI;

@Controller
public class Importer {

	public List<String> langStrings = new ArrayList<String>();
	public HashMap<String,String> learnerRoles = new HashMap<String,String>();
	public HashMap<String,String> staffRoles = new HashMap<String,String>();
	public HashMap<String,String> titleActivities = new HashMap<String,String>();
	public HashMap<String,HashMap<String,Object>> activities = new HashMap<String,HashMap<String,Object>>();
	public HashMap<String,HashMap<String,Object>> environments = new HashMap<String,HashMap<String,Object>>();
	public HashMap<String,HashMap<String,Object>> resources = new HashMap<String,HashMap<String,Object>>();
	public HashMap<String,HashMap<String,Object>> acts = new HashMap<String,HashMap<String,Object>>();
	public List<String> actsOrdered = new ArrayList<String>();
	XPath  xPath;
	Document xmlDocument;
	String learnersXPath = "manifest//organizations//learning-design/components/roles/learner";
	String learnersTitleXPath = "manifest//organizations//learning-design/components/roles/learner/title";
	String staffXPath = "manifest//organizations//learning-design/components/roles/staff";
	String staffsTitleXPath = "manifest//organizations//learning-design/components/roles/staff/title";

	static String learningActivityXPath = "manifest//organizations//learning-design/components/activities/learning-activity";

	static String supportActivityXPath = "manifest//organizations//learning-design/components/activities/support-activity";

	static String activityStructureXPath = "manifest//organizations//learning-design/components/activities/activity-structure";

	static String environmentsXPath = "manifest//organizations//learning-design/components/environments/environment";

	static String playXPath = "manifest//organizations//learning-design/method/play/act/role-part";

	static String resourcesXPath = "manifest//resources/resource";

	static String learningActivityEnvironmentXPath = "manifest//organizations//learning-design/components/activities/learning-activity/environment-ref";
	static String titleXPath = "manifest//organizations//learning-design/title";
	
	private IUnitOfLearningService unitOfLearningService;
	private UserService userService;
	
	
	public void importLD(Document doc, HttpSession session) throws TransformerException{
		User user = userService.get((Integer)session.getAttribute("loginId"));

		NodeList generalList = doc.getElementsByTagName("langstring");

		for( int i = 0 ; i<generalList.getLength(); i++){
			Node node = generalList.item(0).getFirstChild();
			System.out.println(node.getNodeValue());
		}
		
		NodeList titleList = XPathAPI.selectNodeList(doc, titleXPath);
		Node nodeTitle = titleList.item(0);
		String title  = nodeTitle.getTextContent();

		//			xmlDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
					xPath =  XPathFactory.newInstance().	newXPath();
		
		
					NodeList learnersList = XPathAPI.selectNodeList(doc, learnersXPath);
					for(int i=0;i<learnersList.getLength(); i++){
						Node node = learnersList.item(i);
						NamedNodeMap namedNodeMap = node.getAttributes();
						String startId = namedNodeMap.getNamedItem("identifier").toString();
						String titleValue = XPathAPI.selectNodeList(doc, learnersTitleXPath).item(0).getFirstChild().getNodeValue();
						learnerRoles.put(startId, titleValue);
					}
		
					NodeList staffList = XPathAPI.selectNodeList(doc, staffXPath);
					for(int i=0;i<staffList.getLength(); i++){
						Node node = staffList.item(i);
						NamedNodeMap namedNodeMap = node.getAttributes();
						String startId = namedNodeMap.getNamedItem("identifier").toString();
						String titleValue = XPathAPI.selectNodeList(doc, staffsTitleXPath).item(0).getFirstChild().getNodeValue();
						staffRoles.put(startId, titleValue);
					}
		
					NodeList learningActivitiesList = XPathAPI.selectNodeList(doc, learningActivityXPath);
					for(int i=0;i<learningActivitiesList.getLength(); i++){
						Node node = learningActivitiesList.item(i);
						NamedNodeMap namedNodeMap = node.getAttributes();
						String startId = namedNodeMap.getNamedItem("identifier").toString();
						NodeList nodes = node.getChildNodes();
						HashMap<String,Object> attributes = new HashMap<String,Object>();
						List<String> environments = new ArrayList<String>();
						String descTitle = "";
						String descItemRef = "";
						String descItemTitle = "";
						String completeActivity = "";
						for(int j = 0; j<nodes.getLength(); j++){
							Node innerNode = nodes.item(j);
							if("imsld:environment-ref".equals(innerNode.getNodeName())){
								NamedNodeMap envAttrs = innerNode.getAttributes();
								String ref = envAttrs.getNamedItem("ref").toString();
								environments.add(ref);
							}else if("imsld:activity-description".equals(innerNode.getNodeName())){
								NodeList descs = innerNode.getChildNodes();
								for(int k = 0; k<descs.getLength(); k++){
									Node desc = descs.item(k);
									if("imsld:title".equals(desc.getNodeName())){
										descTitle = desc.getTextContent();
									}else if("imsld:item".equals(desc.getNodeName())){
										NamedNodeMap envAttrs = desc.getAttributes();
										String ref = envAttrs.getNamedItem("identifierref").toString();
										descItemRef = ref;
										Node descItemTitleNode = desc.getChildNodes().item(0).getNextSibling();
										descItemTitle = descItemTitleNode.getFirstChild().getNodeValue();
									}
								}
							}else if("imsld:complete-activity".equals(innerNode.getNodeName())){
								NodeList descs = innerNode.getChildNodes();
								Node descItemTitleNode = descs.item(0);
								if(descs.getLength()==0){
									completeActivity = "none";
								}else  if(descs.getLength() > 0){
									if(descItemTitleNode.getNextSibling().getNodeName() == "imsld:user-choice"){
										completeActivity = "userChoice";
									}else{
										completeActivity = descItemTitleNode.getNextSibling().getFirstChild().getNodeValue();
									}
								}
							}
						}
						attributes.put("environments", environments);
						attributes.put("descTitle", descTitle);
						attributes.put("descItemRef", descItemRef);
						attributes.put("descItemTitle", descItemTitle);
						attributes.put("completeActivity", completeActivity);
						activities.put(startId, attributes);
					}
		
		
					NodeList supportActivitiesList = XPathAPI.selectNodeList(doc, supportActivityXPath);
					for(int i=0;i<supportActivitiesList.getLength(); i++){
						Node node = supportActivitiesList.item(i);
						NamedNodeMap namedNodeMap = node.getAttributes();
						String startId = namedNodeMap.getNamedItem("identifier").toString();
						NodeList nodes = node.getChildNodes();
						HashMap<String,Object> attributes = new HashMap<String,Object>();
						List<String> environments = new ArrayList<String>();
						List<String> roles = new ArrayList<String>();
						String descTitle = "";
						String descItemRef = "";
						String descItemTitle = "";
						String completeActivity = "";
						for(int j = 0; j<nodes.getLength(); j++){
							Node innerNode = nodes.item(j);
							if("imsld:environment-ref".equals(innerNode.getNodeName())){
								NamedNodeMap envAttrs = innerNode.getAttributes();
								String ref = envAttrs.getNamedItem("ref").toString();
								environments.add(ref);
							}else if("imsld:role-ref".equals(innerNode.getNodeName())){
								NamedNodeMap envAttrs = innerNode.getAttributes();
								String ref = envAttrs.getNamedItem("ref").toString();
								roles.add(ref);
							}else if("imsld:activity-description".equals(innerNode.getNodeName())){
								NodeList descs = innerNode.getChildNodes();
								for(int k = 0; k<descs.getLength(); k++){
									Node desc = descs.item(k);
									if("imsld:title".equals(desc.getNodeName())){
										descTitle = desc.getTextContent();
									}else if("imsld:item".equals(desc.getNodeName())){
										NamedNodeMap envAttrs = desc.getAttributes();
										String ref = envAttrs.getNamedItem("identifierref").toString();
										descItemRef = ref;
										Node descItemTitleNode = desc.getChildNodes().item(0).getNextSibling();
										descItemTitle = descItemTitleNode.getFirstChild().getNodeValue();
									}
								}
							}else if("imsld:complete-activity".equals(innerNode.getNodeName())){
								NodeList descs = innerNode.getChildNodes();
								Node descItemTitleNode = descs.item(0);
								if(descs.getLength()==0){
									completeActivity = "none";
								}else  if(descs.getLength() > 0){
									if(descItemTitleNode.getNextSibling().getNodeName() == "imsld:user-choice"){
										completeActivity = "userChoice";
									}else{
										completeActivity = descItemTitleNode.getNextSibling().getFirstChild().getNodeValue();
									}
								}
							}
						}
						attributes.put("environments", environments);
						attributes.put("roles", roles);
						attributes.put("descTitle", descTitle);
						attributes.put("descItemRef", descItemRef);
						attributes.put("descItemTitle", descItemTitle);
						attributes.put("completeActivity", completeActivity);
						activities.put(startId, attributes);
					}
		
		
					NodeList activityStructureList = XPathAPI.selectNodeList(doc, activityStructureXPath);
					for(int i=0;i<activityStructureList.getLength(); i++){
						Node node = activityStructureList.item(i);
						NamedNodeMap namedNodeMap = node.getAttributes();
						String startId = namedNodeMap.getNamedItem("identifier").toString();
						String structureType = namedNodeMap.getNamedItem("structure-type").toString();
						NodeList nodes = node.getChildNodes();
						HashMap<String,Object> attributes = new HashMap<String,Object>();
						List<String> la = new ArrayList<String>();
						List<String> sa = new ArrayList<String>();
						for(int j = 0; j<nodes.getLength(); j++){
							Node innerNode = nodes.item(j);
							if("imsld:learning-activity-ref".equals(innerNode.getNodeName())){
								NamedNodeMap envAttrs = innerNode.getAttributes();
								String ref = envAttrs.getNamedItem("ref").toString();
								la.add(ref);
							}else if("imsld:support-activity-ref".equals(innerNode.getNodeName())){
								NamedNodeMap envAttrs = innerNode.getAttributes();
								String ref = envAttrs.getNamedItem("ref").toString();
								sa.add(ref);
							}
						}
						attributes.put("structureType", structureType);
						attributes.put("la", la);
						attributes.put("sa", sa);
						activities.put(startId, attributes);
					}
		
		
					NodeList environmentList = XPathAPI.selectNodeList(doc, environmentsXPath);
					for(int i=0;i<environmentList.getLength(); i++){
						Node node = environmentList.item(i);
						NamedNodeMap namedNodeMap = node.getAttributes();
						String startId = namedNodeMap.getNamedItem("identifier").toString();
						NodeList nodes = node.getChildNodes();
						HashMap<String,Object> attributes = new HashMap<String,Object>();
						List<String> environmentsList = new ArrayList<String>();
						List<String> roles = new ArrayList<String>();
						List<String> items = new ArrayList<String>();
						String titl = "";
						String descTitle = "";
						String descItemRef = "";
						String descItemTitle = "";
						String conferenceManager = "";
						String moderator = "";
						for(int j = 0; j<nodes.getLength(); j++){
							Node innerNode = nodes.item(j);
							if("imsld:title".equals(innerNode.getNodeName())){
								titl = innerNode.getChildNodes().item(0).getNodeValue();
							}else if("imsld:learning-object".equals(innerNode.getNodeName())){
								NodeList descs = innerNode.getChildNodes();
								for(int k = 0; k<descs.getLength(); k++){
									Node desc = descs.item(k);
									if("imsld:item".equals(desc.getNodeName())){
										NamedNodeMap envAttrs1 = desc.getAttributes();
										String ref1 = envAttrs1.getNamedItem("identifierref").toString();
										descItemRef = ref1;
										Node descItemTitleNode = desc.getChildNodes().item(0).getNextSibling();
										descItemTitle = descItemTitleNode.getFirstChild().getNodeValue();
									}
								}
							}else if("imsld:service".equals(innerNode.getNodeName())){
								NodeList descs = innerNode.getChildNodes();
								for(int k = 0; k<descs.getLength(); k++){
									Node desc = descs.item(k);
									if("imsld:conference".equals(desc.getNodeName())){
										NodeList otherNodes = desc.getChildNodes();
										for(int s = 0; s< otherNodes.getLength(); s++){
											Node desc1 = otherNodes.item(s);
											if("imsld:conference-manager".equals(desc1.getNodeName())){
												NamedNodeMap envAttrs1 = desc1.getAttributes();
												String ref1 = envAttrs1.getNamedItem("role-ref").toString();
												conferenceManager = ref1;
											}else if("imsld:moderator".equals(desc1.getNodeName())){
												NamedNodeMap envAttrs1 = desc1.getAttributes();
												String ref1 = envAttrs1.getNamedItem("role-ref").toString();
												moderator = ref1;
											}else if("imsld:item".equals(desc1.getNodeName())){
												NamedNodeMap envAttrs1 = desc1.getAttributes();
												String ref1 = envAttrs1.getNamedItem("identifierref").toString();
												descItemRef = ref1;
												Node descItemTitleNode = desc1.getChildNodes().item(0).getNextSibling();
												descItemTitle = descItemTitleNode.getFirstChild().getNodeValue();
											}
										}
									}
								}
							}
		
						}
						attributes.put("title", titl);
						attributes.put("descTitle", descTitle);
						attributes.put("descItemRef", descItemRef);
						attributes.put("descItemTitle", descItemTitle);
						attributes.put("moderator", moderator);
						attributes.put("conferenceManager", conferenceManager);
						environments.put(startId, attributes);
					}
		
					NodeList actsList = XPathAPI.selectNodeList(doc, playXPath);
					for(int i=0;i<actsList.getLength(); i++){
						Node node = actsList.item(i);
						NodeList nodes = node.getChildNodes();
						for(int j = 0; j<nodes.getLength(); j++){
							Node innerNode = nodes.item(j);
							if("imsld:support-activity-ref".equals(innerNode.getNodeName())){
								NamedNodeMap saAttrs = innerNode.getAttributes();
								String ref = saAttrs.getNamedItem("ref").toString();
								actsOrdered.add(ref);
							}else if("imsld:learning-activity-ref".equals(innerNode.getNodeName())){
								NamedNodeMap envAttrs = innerNode.getAttributes();
								String ref = envAttrs.getNamedItem("ref").toString();
								actsOrdered.add(ref);
							}
						}
					}
		
		
					NodeList resourcesList = XPathAPI.selectNodeList(doc, resourcesXPath);
					for(int i=0;i<resourcesList.getLength(); i++){
						Node node = resourcesList.item(i);
						NamedNodeMap namedNodeMap = node.getAttributes();
						String type = namedNodeMap.getNamedItem("type").toString();
						String identifier = namedNodeMap.getNamedItem("identifier").toString();
						String ref = "";
						NodeList nodes = node.getChildNodes();
						HashMap<String,Object> attributes = new HashMap<String,Object>();
						for(int j = 0; j<nodes.getLength(); j++){
							Node innerNode = nodes.item(j);
							if("file".equals(innerNode.getNodeName())){
								NamedNodeMap envAttrs = innerNode.getAttributes();
								ref = envAttrs.getNamedItem("href").toString();
							}
						}
						attributes.put("type", type);
						attributes.put("identifier", identifier);
						attributes.put("ref", ref);
						resources.put(identifier, attributes);
					}
					
					
					UnitOfLearning unitOfLearning = new UnitOfLearning();
					unitOfLearning.setTitle(title);
					unitOfLearning.setSubject(title);
					unitOfLearning.setAuthor(user);
					unitOfLearning.setDescription(title);
					unitOfLearning = unitOfLearningService.create(unitOfLearning);
					session.setAttribute("unitOfLearningId", unitOfLearning.getId());

		
	}
	
	
	@Resource(name="unitOfLearningService")
	public void setUnitOfLearningService(IUnitOfLearningService unitOfLearningService) {
		this.unitOfLearningService = unitOfLearningService;
	}

	@Resource(name="userService")
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
}
